package com.yeyks.commonReference.service.user.impl;

import cn.hutool.core.comparator.CompareUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.WeightRandom;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.google.common.collect.Maps;
import com.yeyks.activity.dal.domain.ActivityNodeUserRecord;
import com.yeyks.activity.service.ActivityNodeUserRecordService;
import com.yeyks.common.constants.ConfigKey;
import com.yeyks.common.constants.MessageTemplate;
import com.yeyks.common.constants.OrderStatus;
import com.yeyks.common.constants.consumer.UserInviteRelationTypeConstant;
import com.yeyks.common.dto.NewZeroParentRate;
import com.yeyks.common.em.UserBillType;
import com.yeyks.common.em.consumer.UserInviteRelationTypeEnum;
import com.yeyks.common.utils.FormatUtils;
import com.yeyks.common.utils.base.PhoneUtil;
import com.yeyks.commonReference.service.config.ConfigService;
import com.yeyks.commonReference.service.consumer.MessageNoticeTemplateService;
import com.yeyks.commonReference.service.consumer.UserCouponInfoService;
import com.yeyks.commonReference.service.order.OrderHeadService;
import com.yeyks.commonReference.service.user.UserCommissionService;
import com.yeyks.consumer.dal.domain.MessageNotice;
import com.yeyks.consumer.dal.domain.UserInfo;
import com.yeyks.consumer.dal.domain.UserInviteWhiteList;
import com.yeyks.consumer.service.*;
import com.yeyks.order.dal.domain.OrderHead;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * @author shuai
 * @date 2019/11/11 17:52
 */
@Slf4j
@Service
public class UserCommissionServiceImpl implements UserCommissionService {

    @Autowired
    private OrderHeadService orderHeadService;
    @Autowired
    private ConfigService configService;
    @Autowired
    private UserInviteRelationService userInviteRelationService;
    @Autowired
    private UserAccountOverviewService userAccountOverviewService;
    @Autowired
    private MessageNoticeTemplateService messageNoticeTemplateService;
    @Autowired
    private MessageNoticeService messageNoticeService;
    @Autowired
    private UserInfoService userInfoService;
    @Autowired
    private UserCouponInfoService userCouponInfoService;
    @Autowired
    private UserInviteWhiteListService userInviteWhiteListService;
    @Autowired
    private ActivityNodeUserRecordService recordService;

    /**
     * 0元推广订单分佣
     *
     * @param orderHead
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addZeroAmount(OrderHead orderHead) {
        //查询是否是注册7天内下的第一单
        Boolean flag = orderHeadService.userOrderIsRegistTime(orderHead, 7);
        //7天内下的单，0元推广上级分佣5元
        if (flag) {
            //判断是否是第一单
//            if (!orderHeadService.isFirstUserOrder(orderHead)) {
//                log.info("该订单不是用户的第一单userId = {}, orderNO = {}", orderHead.getUserId(), orderHead.getOrderNo());
//                return;
//            }
            NewZeroParentRate newZeroParentRate = configService.getNewZeroParentRate();
            //查询该订单用户的上级(0元邀请)
            Integer parentId = userInviteRelationService.selectParentIdByUserId(orderHead.getUserId(), 1);
            if (null == parentId) {
                log.info("该用户不存在上级orderHead中的userId = {}", orderHead.getUserId());
                return;
            }
            //如果上级邀请人是学生，则不发放佣金
//            List<String> studentsList = configService.getNewZeroUserTypeStudent();
//            if (studentsList != null && studentsList.contains(String.valueOf(parentId))) {
//                log.info("该用户的上级id是学生推手userId = {}，parentId = {}", orderHead.getUserId(), parentId);
//                return;
//            }

            //如果上级在白名单中，且白名单是社会推手则发佣金
//            UserInviteWhiteList userInviteWhiteList = userInviteWhiteListService.getByUserId(parentId);
//            if (null != userInviteWhiteList && (2 == userInviteWhiteList.getType())) {
            addAmount(parentId, newZeroParentRate.getParentFirstOrderRate());
            //写入佣金消息
            messageNotice(parentId, newZeroParentRate.getParentFirstOrderRate());
//            }
        }
    }

    /**
     * 给用户增加金额
     *
     * @param userId
     * @param amount
     */
    private void addAmount(Integer userId, Integer amount) {
        //给上级发佣金
        userAccountOverviewService.addAmount(amount, userId, UserBillType.ZERO_PROFIT.value(), UserBillType.ZERO_PROFIT.desc(), UserInviteRelationTypeConstant.INVITE_ZERO);
    }

    /**
     * 写入佣金消息
     *
     * @param userId
     * @param getAmount
     */
    private void messageNotice(Integer userId, Integer getAmount) {
        String template = MessageTemplate.ORDER_PARENT_COMMISSION;
        Integer type = MessageNotice.Type.order_parent_commission.value();
        try {
            Map<String, Object> param = Maps.newHashMap();
            param.put("getAmount", FormatUtils.fenToYuan(getAmount));
            Map<String, String> map = messageNoticeTemplateService.commonValue(param, template);
            messageNoticeService.activieyCreateAndSave(map, userId, type);
        } catch (Exception e) {
            log.error("佣金写入异常{}", e.getLocalizedMessage());
            e.printStackTrace();
        }
    }

    //推广佣金概率
    private static final WeightRandom<Integer> integerWeightRandom = new WeightRandom<>(
            new WeightRandom.WeightObj[]{
                    new WeightRandom.WeightObj<>(100, 59),
                    new WeightRandom.WeightObj<>(200, 40),
                    new WeightRandom.WeightObj<>(600, 0.6),
                    new WeightRandom.WeightObj<>(800, 0.3),
                    new WeightRandom.WeightObj<>(1800, 0.1)
            }
    );

    //o元邀请佣金 v3.7.1
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveZeroCommission(String phone, String deviceId) {
        UserInfo userInfo = userInfoService.selectUseInfoPhone(phone);
        if (Objects.nonNull(userInfo)) {
            //设备id校验
            if (Objects.equals(userInfo.getNewFlag(), 0)) {
                Integer userId = userInfo.getId();
                //给新用户发两张10元优惠券,v3.8
                userCouponInfoService.createNewCoupon(userId);
                //0元佣金
                Integer parentId = userInviteRelationService.selectParentIdByUserId(userId, UserInviteRelationTypeEnum.PROMOTION.getValue());
                //是否发佣金
                boolean whetherCommission = whetherCommission(parentId);
                if (Objects.nonNull(parentId) && whetherCommission) {
                    //佣金
                    Integer brokerage;
                    UserInviteWhiteList userInviteWhiteList = userInviteWhiteListService.getByUserId(parentId);
                    if (Objects.nonNull(userInviteWhiteList)) {
                        if (Objects.equals(userInviteWhiteList.getType(), 1)) {
                            brokerage = 200;
                        } else {
//                        brokerage = integerWeightRandom.next();
                            brokerage = 0;
                        }
                        if (brokerage > 0) {
                            //添加佣金
                            addAmount(parentId, brokerage);
                            //添加佣金记录
                            messageNoticeZero1(userInfo.getPhone(), parentId, brokerage);
                        }
                    }
                }
                //修改用户的登录记录
                userInfoService.update(
                        new UpdateWrapper<UserInfo>()
                                .set(UserInfo.NEW_FLAG, 1)
                                .eq(UserInfo.ID, userId)
                );
            }
        }
    }

    private boolean whetherCommission(Integer parentId) {
        //禁用开关
        boolean jinYongKaiGuan = CompareUtil.compare(1, Convert.toInt(configService.getValue(ConfigKey.USER_STATUS_ZERO_FORBIDDEN), 0)) != 0;
        //是否在白名单
        boolean ifInWhite = userInviteWhiteListService.isWhite(parentId);
        return jinYongKaiGuan && ifInWhite;
    }

    //写入佣金注册消息 v3.7.1
    @Override
    public void messageNoticeZero(Integer userId, Integer parentId) {
        //是否发佣金
        boolean whetherCommission = whetherCommission(parentId);
        if (whetherCommission) {
            UserInfo userInfo = userInfoService.getById(userId);
            Map<String, Object> map = new HashMap<>();
            map.put("phone", PhoneUtil.replace(userInfo.getPhone()));
            messageNoticeService.saveMessageNoticeSimple(MessageTemplate.INVITE_ZERO_NOTICE, map, parentId, MessageNotice.Type.order_parent_commission.value());
        }
    }

    /**
     * c2b订单新手任务佣金
     */
    @Override
    public void addC2bNewUserTaskAmount(OrderHead orderHead) {
        //任务一：首先判断是否是第一单，是第一单的话判断金额是否满足任务二和任务三
        int count = orderHeadService.count(new QueryWrapper<OrderHead>()
                .eq(OrderHead.USER_ID, orderHead.getUserId())
                .in(OrderHead.STATUS, OrderStatus.postCheckOut, OrderStatus.comment));
        Integer total = orderHead.getSnapshotTotalFee();
        //是第一单，奖励3元
        if (count == 0) {
            sendNewUserTask(300, orderHead.getUserId(), 1);
        }
        //非第一单，判断任务二，是否满足200不满足300元，奖励3元
        if (total >= 20000 && total < 30000) {
            //任务二成立，发放3元奖励
            sendNewUserTask(300, orderHead.getUserId(), 2);
        }
        if (total >= 30000) {
            //任务三成立，发放5元奖励
            sendNewUserTask(500, orderHead.getUserId(), 3);
        }
    }

    /**
     * 新人任务佣金写入
     *
     * @param amount
     * @param userId
     * @param taskType 1任务一，2任务二，3任务三
     */
    private void sendNewUserTask(Integer amount, Integer userId, Integer taskType) {
        //任务二成立，发放3元奖励
        if (userAccountOverviewService.addAmount(amount, userId,
                UserBillType.NEW_USER_TASK.value(),
                UserBillType.NEW_USER_TASK.desc(),
                UserInviteRelationTypeConstant.NEW_USER_TASK)) {
            //写入节点表
            if (recordService.save(new ActivityNodeUserRecord().setActivityCode("NewUserTask").setNode(String.valueOf(taskType)).setUserId(userId).setCreateTime(new Date()))) {
                String phone = userInfoService.getPhoneById(userId);
                if (null != phone) {
                    //TODO 发送短信

                }
            }
        }
    }

    //写入佣金消息 v3.7.1
    private void messageNoticeZero1(String phone, Integer parentId, Integer amount) {
        Map<String, Object> map = new HashMap<>();
        if (Objects.nonNull(parentId)) {
            map.put("phone", PhoneUtil.replace(phone));
            map.put("amount", FormatUtils.fenToYuan(amount));
            messageNoticeService.saveMessageNoticeSimple(MessageTemplate.INVITE_ZERO_COMMISSION, map, parentId, MessageNotice.Type.order_parent_commission.value());
        }
    }

}
